function MyEvent() {
  // 准备一个数据结构用于缓存订阅者信息
  this._events = Object.create(null)
}

MyEvent.prototype.on = function (type, callback) {
  // 判断当前次的事件是否已经存在,然后再决定如何做缓存
  if (this._events[type]) {
    this._events[type].push(callback)
  } else {
    this._events[type] = [callback]
  }
}

MyEvent.prototype.emit = function (type, ...args) {
  if (this._events[type] && this._events[type].length) {
    this._events[type].forEach((callback) => {
      callback(...args)
    })
  }
}
MyEvent.prototype.off = function (type, callback) {
  // 判断当前 type
  if (this._events && this._events[type]) {
    this._events[type] = this._events[type].filter((item) => {
      return item != callback && item.link != callback
    })
  }
}

MyEvent.prototype.once = function (type, callback) {
  let doOnce = function (...args) {
    callback.call(this, ...args)
    this.off(type, doOnce)
  }
  doOnce.link = callback
  this.on(type, doOnce)
}

const ev = new MyEvent()
const fn = function (...data) {
  console.info('e_1 执行1', data)
}
ev.on('e_1', fn)
// ev.on('e_1', () => {
//   console.info('e_1 执行2')
// })

ev.emit('e_1', '前')
ev.off('e_1', fn)
ev.emit('e_1', '后')
